#include "CalendarRenderer.h"

CalendarRenderer::CalendarRenderer() {
    this->currentMonth = 1;
    this->currentYear = 1990;
    this->calendar = NULL;
}

CalendarRenderer::CalendarRenderer(const CalendarRenderer& copied) {
    this->currentMonth = copied.currentMonth;
    this->currentYear = copied.currentYear;
    this->calendar = copied.calendar;
}

CalendarRenderer::CalendarRenderer(Calendar* cal, int month, int year) {
    this->calendar = cal;
    this->currentMonth = month;
    this->currentYear = year;
}

CalendarRenderer& CalendarRenderer::operator=(const CalendarRenderer& copied) {
    this->currentMonth = copied.currentMonth;
    this->currentYear = copied.currentYear;
    this->calendar = copied.calendar;
    return *this;
}

CalendarRenderer::~CalendarRenderer() {
    this->currentMonth = -1;
    this->currentYear = -1;
    this->calendar = NULL;
}

Calendar* CalendarRenderer::GetCalendar() {
    return calendar;
}

int CalendarRenderer::GetCurrentMonth() {
    return currentMonth;
}

int CalendarRenderer::GetCurrentYear() {
    return currentYear;
}

void CalendarRenderer::SetCalendar(Calendar *calendar) {
    this->calendar = calendar;
}

void CalendarRenderer::SetCurrentMonth(int month) {
    this->currentMonth = month;
}

void CalendarRenderer::SetCurrentYear(int year) {
    this->currentYear = year;
}

void CalendarRenderer::AdvanceMonth() {
    currentMonth++;
    if (currentMonth == 13) {
        currentMonth = 1;
        currentYear++;
    }
}

void CalendarRenderer::BackMonth() {
    currentMonth--;
    if (currentMonth == 0) {
        currentMonth = 12;
        currentYear--;
    }
}

void CalendarRenderer::RenderCalendar() {
    int iter, dayIter, dayMax = calendar->MaxDaysInMonth(currentMonth, currentYear);
    int dayHeader = 0;
    int currDay = calendar->GetFirstDay(currentYear, currentMonth);
    string dayString[] = {"Ahad  ", "Senin ", "Selasa", "Rabu  ", "Kamis ", "Jumat ", "Sabtu ", "Undef "};
    
    currDay %= 7;
    // print header
#ifdef _WIN32
    system("cls");
#endif
    printf("Month %02i, Year %04i", currentMonth, currentYear);
    EndLine();
#ifdef _WIN32
    printf("Press '%c' to next month, '%c' to previous month, and ESC to exit", RIGHT_KEY, LEFT_KEY);
#endif
    EndLine();
    // end of print header, start of print first row
    EndLine();
    PrintHLine();
    EndLine();
    printf("%c", V_STRIP);
    for (iter = 0; iter < DAY_IN_WEEK_MAX; iter++) {
        printf("%s%c", dayString[dayHeader].c_str(), V_STRIP); // print day
        dayHeader++;
    }
    EndLine();
    PrintHLine();
    // end of print first row
    EndLine();
    printf("%c", V_STRIP);
    for (iter = 0; iter < currDay; iter++) {
        printf("      %c", V_STRIP); // start filler
    }
    for (dayIter = 1; dayIter <= dayMax; dayIter++) {
        tm __time = {0,0,0,dayIter, currentMonth-1, currentYear-1900};
        vector<long> eventEntries = calendar->GetEventCountInDay(&__time);
        if (eventEntries.size() > 0) {
            printf("%02i.%03i%c", dayIter, eventEntries.size(), V_STRIP); // prints count of event
        } else {
            printf("%02i.   %c", dayIter, V_STRIP); // prints nothing if there is no event
        }
        currDay++;
        if (currDay == DAY_IN_WEEK_MAX) {
            currDay -= DAY_IN_WEEK_MAX; // reset day 
            EndLine();
            PrintHLine(); // print new horizontal line
            EndLine();
            if (dayIter < dayMax) {
                printf("%c", V_STRIP);
            }
        }
    }
    if (currDay != 0) {
        for (iter = currDay; iter < DAY_IN_WEEK_MAX; iter++) {
            printf("      %c", V_STRIP); // end filler
        }
        EndLine();
        PrintHLine();
    }
    EndLine();
}

void CalendarRenderer::EndLine() {
    printf("\n");
}

void CalendarRenderer::PrintHLine() {
    int iter;
    printf("%c", H_STRIP);
    for (iter = 0; iter < DAY_IN_WEEK_MAX; iter++) {
        printf("%s", H_CELL);
    }
}

void CalendarRenderer::ShowCalendar(char**args) {
    if (args[2] && args[3]) {
        if (calendar->EmptyEvent()) {
            printf("The calendar is empty\n");
        } else {
            char readChar;
            currentYear = atoi(args[2]); // set year
            currentMonth = atoi(args[3]); // set month
#ifdef _WIN32
            do {
#endif
                RenderCalendar(); // print calendar
#ifdef _WIN32
                readChar = getch();
                if (readChar == RIGHT_KEY)
                    AdvanceMonth();
                else if (readChar == LEFT_KEY)
                    BackMonth();
            } while (readChar != ESC_KEY);
#endif
        }
    }
}

